/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.javlov.vf;

import net.javlov.State;

public class ValueArray<T> implements ValueTable<T> {
	
	private static final long serialVersionUID = 4921396704020363220L;

	protected Value[] values;
	
	protected ValueFunction<T> initializer;
	
	public ValueArray(int size) {
		values = new Value[size];
	}

	@Override
	public Value get(State<? extends T> s) {
		Value val = values[s.getID()];
		if ( val == null )
			val = new Value( getInitialValue(s) );
		return val;
	}

	@Override
	public void setInitializer(ValueFunction<T> vf) {
		initializer = vf;		
	}

	public double getInitialValue(State<? extends T> s) {
		if ( initializer == null )
			return 0;
		return initializer.getValue(s);
	}
	
	@Override
	public double getValue(State<? extends T> s) {
		return get(s).get();
	}

	@Override
	public void init() {
		values = new Value[values.length];		
	}
	
	public void reset() {}

	@Override
	public Double queryValue(State<? extends T> s) {
		Value val = values[s.getID()];
		if ( val == null )
			return null;
		return val.get();
	}

	@Override
	public void setValue(State<? extends T> s, double value) {
		Value val = values[s.getID()];
		if ( val == null )
			val = new Value( value );
		else
			val.set(value);
	}

	@Override
	public void update(State<? extends T> s, double delta) {
		Value val = values[s.getID()];
		if ( val == null )
			throw new UnknownStateException(s.toString());
		val.add(delta);
	}

	@Override
	public void set(State<? extends T> s, Value val) {
		values[s.getID()] = val;		
	}

	@Override
	public int size() {
		return values.length;
	}

}
